{% extends 'admin/base.html' %}
{% block title %}预测模型管理 - 天气系统管理后台{% endblock %}
{% block head %}
{{ super() }}
<style>
    .modal-dialog {
        overflow-y: auto;
        margin: 1.75rem auto;
        max-width: 800px;
    }

    .modal-backdrop {
        position: fixed;
        top: 0;
        left: 0;
        z-index: 1040;
        width: 100vw;
        height: 100vh;
        background-color: rgba(0, 0, 0, 0.5);
    }

    .modal {
        position: fixed;
        top: 0;
        left: 0;
        z-index: 1050;
        width: 100%;
        height: 100%;
        overflow-x: hidden;
        overflow-y: auto;
        outline: 0;
    }

    #chart-container {
        width: 100%;
        height: 400px;
        margin: 0 auto;
        position: relative;
    }
</style>
{% endblock %}

{% block extra_js %}
<script src="{{ url_for('static', filename='echart/echarts.min.js') }}"></script>
<script>
    let myChart = null;  // 声明全局变量

    // 检查依赖项是否正确加载
    function checkDependencies() {
        if (typeof bootstrap === 'undefined') {
            console.error('Bootstrap JavaScript is not loaded!');
            return false;
        }
        if (typeof echarts === 'undefined') {
            console.error('ECharts is not loaded!');
            return false;
        }
        return true;
    }

    // 销毁图表实例
    function disposeChart() {
        if (myChart) {
            try {
                myChart.dispose();
                myChart = null;
            } catch (e) {
                console.error('Error disposing chart:', e);
            }
        }
    }

    // 显示预测数据模态框的函数
    function showPredictionModal(city) {
        console.log('Showing prediction modal for city:', city);
        
        // 检查依赖项
        if (!checkDependencies()) {
            console.error('Dependencies check failed');
            return;
        }

        try {
            // 更新模态框标题
            const modalTitleElement = document.getElementById('modal-city-name');
            console.log('Modal title element:', modalTitleElement);
            if (modalTitleElement) {
                modalTitleElement.textContent = `${city} 未来7天气温预测`;
            }
            
            // 获取模态框元素
            const modalElement = document.getElementById('predictionModal');
            console.log('Modal element:', modalElement);
            if (!modalElement) {
                console.error('Modal element not found!');
                return;
            }

            // 初始化模态框 (使用 Bootstrap 5 的方式)
            const predictionModal = new bootstrap.Modal(modalElement, {
                backdrop: 'static',
                keyboard: false
            });
            console.log('Modal initialized');
            
            // 监听模态框隐藏事件
            modalElement.addEventListener('hidden.bs.modal', function () {
                console.log('Modal hidden event triggered');
                disposeChart();
            });
            
            // 显示模态框
            predictionModal.show();
            console.log('Modal shown');

            // 等待模态框完全显示后再初始化图表
            modalElement.addEventListener('shown.bs.modal', function () {
                console.log('Modal shown event triggered');
                // 显示加载状态
                const chartContainer = document.getElementById('chart-container');
                console.log('Chart container:', chartContainer);
                
                // 设置图表容器的尺寸
                chartContainer.style.width = '100%';
                chartContainer.style.height = '400px';
                
                chartContainer.innerHTML = '<div class="text-center p-4"><div class="spinner-border text-primary" role="status"><span class="visually-hidden">Loading...</span></div><p class="mt-2">正在生成预测数据...</p></div>';

                // 确保容器尺寸正确
                setTimeout(() => {
                    try {
                        console.log('Initializing chart...');
                        // 初始化 ECharts
                        if (myChart) {
                            myChart.dispose();
                        }
                        myChart = echarts.init(chartContainer);
                        console.log('Chart initialized');
                        myChart.showLoading({
                            text: '加载中...',
                            maskColor: 'rgba(255, 255, 255, 0.8)',
                            textColor: '#000'
                        });
                        
                        // 发送预测请求
                        console.log('Fetching prediction data...');
                        fetch(`/predict_weather/${city}`)
                            .then(response => {
                                console.log('Received response:', response);
                                if (!response.ok) {
                                    throw new Error('Network response was not ok');
                                }
                                return response.json();
                            })
                            .then(data => {
                                console.log('Parsed prediction data:', data);
                                myChart.hideLoading();
                                
                                if (data.status === 'success' && data.predictions) {
                                    const { dates, temp_max, temp_min } = data.predictions;
                                    console.log('Dates:', dates);
                                    console.log('Max temps:', temp_max);
                                    console.log('Min temps:', temp_min);
                                    
                                    // 配置图表选项
                                    const option = {
                                        title: {
                                            text: `${city} 未来7天气温预测`,
                                            left: 'center'
                                        },
                                        tooltip: {
                                            trigger: 'axis',
                                            formatter: function(params) {
                                                const date = params[0].axisValue;
                                                const maxTemp = params[0].data.toFixed(1);
                                                const minTemp = params[1].data.toFixed(1);
                                                return `${date}<br/>最高温: ${maxTemp}°C<br/>最低温: ${minTemp}°C`;
                                            }
                                        },
                                        legend: {
                                            data: ['最高温度', '最低温度'],
                                            top: 30
                                        },
                                        grid: {
                                            left: '3%',
                                            right: '4%',
                                            bottom: '3%',
                                            top: '80',
                                            containLabel: true
                                        },
                                        xAxis: {
                                            type: 'category',
                                            boundaryGap: false,
                                            data: dates.map(date => {
                                                const d = new Date(date);
                                                return `${d.getMonth() + 1}-${d.getDate()}`;
                                            }),
                                            axisLabel: {
                                                formatter: '{value}'
                                            }
                                        },
                                        yAxis: {
                                            type: 'value',
                                            name: '温度 (°C)',
                                            axisLabel: {
                                                formatter: '{value}°C'
                                            }
                                        },
                                        series: [
                                            {
                                                name: '最高温度',
                                                type: 'line',
                                                data: temp_max,
                                                smooth: true,
                                                symbol: 'circle',
                                                symbolSize: 8,
                                                lineStyle: {
                                                    width: 3,
                                                    color: '#e65100'
                                                },
                                                itemStyle: {
                                                    color: '#e65100'
                                                },
                                                areaStyle: {
                                                    color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                                                        { offset: 0, color: 'rgba(230, 81, 0, 0.8)' },
                                                        { offset: 1, color: 'rgba(230, 81, 0, 0.1)' }
                                                    ])
                                                }
                                            },
                                            {
                                                name: '最低温度',
                                                type: 'line',
                                                data: temp_min,
                                                smooth: true,
                                                symbol: 'circle',
                                                symbolSize: 8,
                                                lineStyle: {
                                                    width: 3,
                                                    color: '#1e88e5'
                                                },
                                                itemStyle: {
                                                    color: '#1e88e5'
                                                },
                                                areaStyle: {
                                                    color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                                                        { offset: 0, color: 'rgba(30, 136, 229, 0.8)' },
                                                        { offset: 1, color: 'rgba(30, 136, 229, 0.1)' }
                                                    ])
                                                }
                                            }
                                        ]
                                    };
                                    
                                    // 设置图表选项
                                    myChart.setOption(option);
                                    
                                    // 添加窗口大小改变时的自适应
                                    window.addEventListener('resize', function() {
                                        myChart && myChart.resize();
                                    });
                                } else {
                                    chartContainer.innerHTML = `<div class="alert alert-danger">${data.message || '获取预测数据失败'}</div>`;
                                }
                            })
                            .catch(error => {
                                myChart.hideLoading();
                                console.error('预测请求失败:', error);
                                chartContainer.innerHTML = '<div class="alert alert-danger">系统错误，请稍后再试</div>';
                            });
                    } catch (error) {
                        console.error('Error initializing chart:', error);
                        chartContainer.innerHTML = '<div class="alert alert-danger">初始化图表失败</div>';
                    }
                }, 100);
            }, { once: true });
        } catch (error) {
            console.error('Error showing modal:', error);
        }
    }

    // 页面加载完成后初始化事件监听
    document.addEventListener('DOMContentLoaded', function() {
        // 点击"查看预测"按钮的事件委托
        document.querySelector('.table').addEventListener('click', function(event) {
            const predictBtn = event.target.closest('.predict-btn');
            if (predictBtn) {
                const city = predictBtn.dataset.city;
                showPredictionModal(city);
            }
        });

        // 关闭按钮事件监听
        document.querySelectorAll('[data-bs-dismiss="modal"]').forEach(button => {
            button.addEventListener('click', function() {
                disposeChart();
            });
        });

        // 点击模态框背景关闭
        document.querySelector('.modal-backdrop')?.addEventListener('click', function() {
            disposeChart();
        });

        // 初始化所有工具提示
        var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'));
        tooltipTriggerList.map(function (tooltipTriggerEl) {
            return new bootstrap.Tooltip(tooltipTriggerEl);
        });
    });

    $(document).ready(function() {
        // 获取所有flash消息，排除class为persistent-alert的元素
        var flashMessages = $('.alert:not(.persistent-alert)');
        flashMessages.each(function() {
            var $message = $(this);
            setTimeout(function() {
                $message.alert('close');
            }, 3000);
        });

        // 重置按钮事件
        $('#reset-button').click(function() {
            $('#search-input').val('');
            const urlParams = new URLSearchParams(window.location.search);
            urlParams.delete('search');
            urlParams.delete('page');
            window.location.href = `${window.location.pathname}?${urlParams.toString()}`;
        });

        // 排序按钮点击事件
        $('#sort-button').click(function() {
            const newSortOrder = "{{ sort_order }}" === 'asc' ? 'desc' : 'asc';
            window.location.href = `{{ url_for('admin_prediction_models') }}?page=1&sort_order=${newSortOrder}&search=${encodeURIComponent("{{ search }}")}`;
        });

        // 更新分页
        updatePagination({{ page }}, {{ total_pages }}, "{{ search }}");
    });

    // 更新分页控件
    function updatePagination(currentPage, totalPages, search) {
        if (totalPages <= 1) {
            return;
        }

        const $pagination = $('#pagination');
        $pagination.empty();

        // 上一页
        const $prevLi = $('<li>').addClass(`page-item ${currentPage <= 1 ? 'disabled' : ''}`);
        const $prevLink = $('<a>').addClass('page-link').text('上一页').attr('href', '#');
        if (currentPage > 1) {
            $prevLink.click(function(e) {
                e.preventDefault();
                window.location.href = `{{ url_for('admin_prediction_models') }}?page=${currentPage - 1}&sort_order={{ sort_order }}&search=${encodeURIComponent(search)}`;
            });
        }
        $prevLi.append($prevLink);
        $pagination.append($prevLi);

        // 计算显示的页码范围
        let startPage = Math.max(1, currentPage - 2);
        let endPage = Math.min(totalPages, startPage + 4);
        if (endPage - startPage < 4 && startPage > 1) {
            startPage = Math.max(1, endPage - 4);
        }

        // 第一页
        if (startPage > 1) {
            const $firstLi = $('<li>').addClass('page-item');
            const $firstLink = $('<a>').addClass('page-link').text('1').attr('href', '#');
            $firstLink.click(function(e) {
                e.preventDefault();
                window.location.href = `{{ url_for('admin_prediction_models') }}?page=1&sort_order={{ sort_order }}&search=${encodeURIComponent(search)}`;
            });
            $firstLi.append($firstLink);
            $pagination.append($firstLi);

            // 如果不是紧接着第一页，显示省略号
            if (startPage > 2) {
                const $ellipsisLi = $('<li>').addClass('page-item disabled');
                const $ellipsisSpan = $('<span>').addClass('page-link').text('...');
                $ellipsisLi.append($ellipsisSpan);
                $pagination.append($ellipsisLi);
            }
        }

        // 页码
        for (let i = startPage; i <= endPage; i++) {
            const $pageLi = $('<li>').addClass(`page-item ${i === currentPage ? 'active' : ''}`);
            const $pageLink = $('<a>').addClass('page-link').text(i).attr('href', '#');
            if (i !== currentPage) {
                $pageLink.click(function(e) {
                    e.preventDefault();
                    window.location.href = `{{ url_for('admin_prediction_models') }}?page=${i}&sort_order={{ sort_order }}&search=${encodeURIComponent(search)}`;
                });
            }
            $pageLi.append($pageLink);
            $pagination.append($pageLi);
        }

        // 如果不是紧接着最后一页，显示省略号
        if (endPage < totalPages - 1) {
            const $ellipsisLi = $('<li>').addClass('page-item disabled');
            const $ellipsisSpan = $('<span>').addClass('page-link').text('...');
            $ellipsisLi.append($ellipsisSpan);
            $pagination.append($ellipsisLi);
        }

        // 最后一页
        if (endPage < totalPages) {
            const $lastLi = $('<li>').addClass('page-item');
            const $lastLink = $('<a>').addClass('page-link').text(totalPages).attr('href', '#');
            $lastLink.click(function(e) {
                e.preventDefault();
                window.location.href = `{{ url_for('admin_prediction_models') }}?page=${totalPages}&sort_order={{ sort_order }}&search=${encodeURIComponent(search)}`;
            });
            $lastLi.append($lastLink);
            $pagination.append($lastLi);
        }

        // 下一页
        const $nextLi = $('<li>').addClass(`page-item ${currentPage >= totalPages ? 'disabled' : ''}`);
        const $nextLink = $('<a>').addClass('page-link').text('下一页').attr('href', '#');
        if (currentPage < totalPages) {
            $nextLink.click(function(e) {
                e.preventDefault();
                window.location.href = `{{ url_for('admin_prediction_models') }}?page=${currentPage + 1}&sort_order={{ sort_order }}&search=${encodeURIComponent(search)}`;
            });
        }
        $nextLi.append($nextLink);
        $pagination.append($nextLi);
    }
</script>
{% endblock %}

{% block content %}
<div class="row mb-3">
    <div class="col-12 d-flex justify-content-between align-items-center">
        <h2>预测模型管理</h2>
    </div>
</div>
<hr>
<div class="alert alert-info persistent-alert">
    <p><strong>提示：</strong> 在此页面，您可以管理各个城市的天气预测模型。对于每个城市，您可以：</p>
    <ul>
        <li>查看当前模型状态</li>
        <li>重新训练城市的预测模型</li>
        <li>查看预测结果</li>
    </ul>
    <p>重新训练可能需要一些时间，请耐心等待。</p>
</div>
<div class="row mb-3 justify-content-center">
    <div class="col-md-4">
        <form id="search-form" method="GET" action="{{ url_for('admin_prediction_models') }}">
            <div class="input-group">
                <input type="text"
                       class="form-control"
                       name="search"
                       id="search-input"
                       placeholder="输入城市名称搜索..."
                       value="{{ search }}">
                <button class="btn btn-outline-primary btn-sm" type="submit">
                    <i class="fas fa-search"></i>
                </button>
                <button class="btn btn-outline-secondary btn-sm" type="button" id="reset-button">
                    <i class="fas fa-undo"></i>
                </button>
            </div>
        </form>
    </div>
</div>
<div class="card">
    <div class="card-body">
        <table class="table table-striped table-bordered">
            <thead>
            <tr>
                <th class="col-2 text-center">城市</th>
                <th class="col-3 text-center">模型状态</th>
                <th class="col-3 text-center">
                    上次训练时间
                    <button id="sort-button" class="btn btn-sm btn-light" data-bs-toggle="tooltip"
                            data-bs-placement="top"
                            title="{% if sort_order == 'asc' %}点击切换为降序{% else %}点击切换为升序{% endif %}">
                        <i class="fas {% if sort_order == 'asc' %}fa-sort-up{% else %}fa-sort-down{% endif %}"></i>
                    </button>
                </th>
                <th class="col-3 text-center">操作</th>
            </tr>
            </thead>
            <tbody>
            {% for city in cities %}
            <tr>
                <td class="col-2 text-center">{{ city }}</td>
                <td class="col-3 text-center">
                    {% set model_file = city + '_weather_model.joblib' %}
                    {% if model_file in existing_models %}
                    <span class="badge bg-success text-white fw-bold">已训练</span>
                    {% else %}
                    <span class="badge bg-warning text-dark fw-bold">未训练</span>
                    {% endif %}
                </td>
                <td class="col-3 text-center">
                    {{ model_timestamps.get(city, '未知') }}
                </td>
                <td class="col-3 text-center">
                    {% if model_file in existing_models %}
                    <a href="{{ url_for('admin_retrain_model', city=city) }}" class="btn btn-sm btn-primary">
                        重新训练
                    </a>
                    <button class="btn btn-sm btn-info predict-btn" data-city="{{ city }}">
                        查看预测
                    </button>
                    {% else %}
                    <a href="{{ url_for('admin_retrain_model', city=city) }}" class="btn btn-sm btn-success">
                        开始训练
                    </a>
                    {% endif %}
                </td>
            </tr>
            {% endfor %}
            </tbody>
        </table>
        {# 分页导航 #}
        <nav aria-label="Page navigation" id="pagination-container" class="mb-3">
            <ul class="pagination justify-content-center" id="pagination">
                <!-- 分页将通过JavaScript动态生成 -->
            </ul>
        </nav>
    </div>
</div>

<!-- 预测结果模态框 -->
<div class="modal fade" id="predictionModal" tabindex="-1" aria-labelledby="predictionModalLabel" aria-hidden="true">
    <div class="modal-dialog modal-lg">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title" id="modal-city-name">城市预测</h5>
                <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
            </div>
            <div class="modal-body">
                <div id="chart-container"></div>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">关闭</button>
            </div>
        </div>
    </div>
</div>

<!-- 添加模态框背景 -->
<div class="modal-backdrop fade show" style="display: none;"></div>
{% endblock %}